﻿using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using FFmpegVideoClip.Configuration;
using FFmpegVideoClip.Lib;
using FFmpegVideoClip.Lib.AdvancedFragmentProcessor;
using FFmpegVideoClip.Mode;
using FFmpegVideoClip.Mode.Files;
using Microsoft.WindowsAPICodePack.Dialogs;

namespace FFmpegVideoClip.windows
{
    /// <summary>
    /// Other.xaml 的交互逻辑
    /// </summary>
    public partial class Other : Page
    {


        public Other()
        {
            InitializeComponent();

        }

        private void ClosePage_Button_Click(object sender, RoutedEventArgs e)
        {
            //MouseButtonEventArgs args = new MouseButtonEventArgs(Mouse.PrimaryDevice, 0, MouseButton.Left); 
            //args.RoutedEvent = Button.ClickEvent; 
            ((MainWindow)Application.Current.MainWindow).CloseSub.RaiseEvent(e);
        }
        private void SelectOutPath_Button_Click(object sender, RoutedEventArgs e)
        {
            string? path = null;
            if (!string.IsNullOrEmpty( FilesMode.Instance.OutPath))
                path = FilesMode.Instance.OutPath;
            else
            if (FilesMode.Instance.FileInfos.Count > 0)
                path = FilesMode.Instance.FileInfos.GroupBy(p => p.Directory).MaxBy(p => p.Count())?.Key;


            using (CommonOpenFileDialog dialog = new CommonOpenFileDialog())
            {
                dialog.Title = "选择保存路径";
                dialog.IsFolderPicker = true;
                dialog.InitialDirectory = !string.IsNullOrEmpty(path) ? path : Environment.GetFolderPath(Environment.SpecialFolder.MyComputer);
                dialog.EnsurePathExists = true;
                if (dialog.ShowDialog() == CommonFileDialogResult.Cancel)
                    return;
                FilesMode.Instance.OutPath = dialog.FileName;
            }
        }
        private void ListBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key != Key.Delete)
                return;
            ListBox lb=(ListBox)sender;
            if(lb.SelectedItems.Count < 0)
                return;
            foreach (Mode.Files.FileInfo item in lb.SelectedItems.Cast<Mode.Files.FileInfo>().ToArray())
                FilesMode.Instance.FileInfos.Remove(item);
        }

        private void SelectPreset_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (e.AddedItems.Count > 0 && e.AddedItems[0] is Preset preset)
            {
                FilesMode.Instance.CurrentPrest.Name = preset.Name;
                FilesMode.Instance.CurrentPrest.SetFlows(preset.Flows, preset.AfterprocessingFlows);
            }
        }

        private void AddFlowToPreset_Button_Click(object sender, RoutedEventArgs e)=> FlowSelect.ShowWindow(true);

        private void DeleteFlow_Button_Click(object sender, RoutedEventArgs e)
        {
            if (FlowsList.SelectedItem is null)
                return;
            FilesMode.Instance.CurrentPrest.Flows.Remove((AdvancedParametersSchemeModule)FlowsList.SelectedItem);
        }
        private void SaveConfig_Button_Click(object sender, RoutedEventArgs e)
        {
            Config.Save(Application.Current.MainWindow);
            TimeWindowShow.ShowTimeDialog();
        }

        private void SavePrest_Button_Click(object sender, RoutedEventArgs e)
        {
            if (SelectPreset.SelectedItem is null)
                return;
            ((Preset)SelectPreset.SelectedItem).SetFlows(FilesMode.Instance.CurrentPrest.Flows, FilesMode.Instance.CurrentPrest.AfterprocessingFlows);
            SaveConfig_Button_Click(null!, null!);
        }
        private void PrestSaveAs_Button_Click(object sender, RoutedEventArgs e)
        {
            if(FilesMode.Instance.CurrentPrest.Flows.Count < 1)
            {
                MessageBoxEx.Show(Application.Current.MainWindow, "尚无可保存的项", "保存错误", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }
            if (!InputTextWindow.ShowInputTextDialog(Application.Current.MainWindow, "预设名称", out string Result))
                return;
            Preset preset = new() { Name = Result };
            preset.SetFlows(FilesMode.Instance.CurrentPrest.Flows, FilesMode.Instance.CurrentPrest.AfterprocessingFlows);
            Config.Instance.Presets.Add(preset);
            SaveConfig_Button_Click(null!, null!);
        }
        private void DeletePrest_Button_Click(object sender, RoutedEventArgs e)
        {
            if (SelectPreset.SelectedItem is null)
                return;
            if (MessageBoxEx.Show(Application.Current.MainWindow, "该操作不可恢复！\r\n该操作不储存配置，如需保存到配置请另行操作!\r\n确认要删除当前选中的预设么？", "删除确认", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel) == MessageBoxResult.Cancel)
                return;
            Config.Instance.Presets.Remove((Preset)SelectPreset.SelectedItem);
            SelectPreset.SelectedIndex = -1;
        }

        private void ListBox_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
        {
            if (!e.Handled)
            {
                e.Handled = true;
                if (((Control)sender).Parent is UIElement parent)
                    parent.RaiseEvent(new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta) { RoutedEvent = MouseWheelEvent, Source = sender });
            }
        }

        private void InputSelect_ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (e.AddedItems.Count < 1 || e.AddedItems[0] is not AdvancedParametersSchemeModule module)
                return;
            if (module == AdvancedParametersSchemeModule.ComboBoxSelectSourceUIItem)
                ((ComboBox)sender).SelectedIndex = -1;

        }
        private void FlowSelect_ComboBox_DropDownOpened(object sender, EventArgs e)
        {
            ComboBox cb = (ComboBox)sender;
            FrameworkElement fe;
            AdvancedParametersSchemeModule CurrentModule;

            fe = (FrameworkElement)VisualTreeHelper.GetParent(cb);

            while (fe!.DataContext is not AdvancedParametersSchemeModule)
            {
                fe = (FrameworkElement)VisualTreeHelper.GetParent(fe);
            }
            CurrentModule = (AdvancedParametersSchemeModule)fe.DataContext;

            AdvancedParametersSchemeModule module = cb.Items.Cast<AdvancedParametersSchemeModule>().First(p => p == CurrentModule);

            Task.Run(() =>
            {
                Thread.Sleep(500);
                cb.Dispatcher.BeginInvoke(() =>
                {
                    ((ComboBoxItem)cb.ItemContainerGenerator.ContainerFromItem(module)).IsEnabled = false;
                });

            });
        }

        private void Execute_Button_Click(object sender, RoutedEventArgs e)
        {
            if(!Tools.CheckFlowsParameter(FilesMode.Instance.CurrentPrest.Flows,out string info))
            {
                MessageBoxEx.Show(Application.Current.MainWindow, info, "未赋值的参数", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }

            FilesMode.Execute();
        }

        private void ListBox_PreviewDrop(object sender, DragEventArgs e)
        {
            if (!e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                Tools.ObservableCollection_Drop<ListBoxItem, Mode.Files.FileInfo>(sender, e, FilesMode.Instance.FileInfos, DragDropEffects.Move, false);
                e.Handled = true;
                return;
            }
            string[] path = (string[])e.Data.GetData(DataFormats.FileDrop);
            if (string.IsNullOrEmpty(FilesMode.Instance.OutPath))
                FilesMode.Instance.OutPath = System.IO.Path.GetDirectoryName(path[0]) ?? string.Empty;

            foreach (string item in path)
            {
                if (string.IsNullOrEmpty(item) || !File.Exists(item))
                    continue;
                GetMediaInfo.MediaInfoResult info = GetMediaInfo.GetInfo(item);
                if (!info.IsValidFile)
                    continue;
                FilesMode.Instance.FileInfos.Add(new(item, info.Duration, info.IsVideoStream, info.IsAudioStream, info.IsSubStream, info.Width, info.Height));
            }
            e.Handled = true;
        }
        private void Preset_MouseMove(object sender, MouseEventArgs e) => Tools.ObservableCollection_DropMove<ListBox, Mode.Files.FileInfo>(sender, e, DragDropEffects.Move);
        private void ShowLog_Button_Click(object sender, RoutedEventArgs e)
        {
            LogInfoWindow.ShowLogInfo();
        }

        private void ParameterValue_TextBox_PreviewDragOver(object sender, DragEventArgs e)
        {
            e.Handled = true;
        }
        private void ParameterValue_TextBox_PreviewDrop(object sender, DragEventArgs e)
        {
            TextBox textBox= (TextBox)sender;
            if (textBox.DataContext is not ParametersSign sign)
                return;
            if (!sign.SignName.StartsWith(ParametersSign.InputSignName, StringComparison.OrdinalIgnoreCase))
                return;
            if (!e.Data.GetDataPresent(DataFormats.FileDrop))
                return;

            string path = ((string[])e.Data.GetData(DataFormats.FileDrop))[0];
            if (!File.Exists(path))
                return;
            sign.Parameter = $"\"{path}\"";
        }


        #region 方案拖动排序
        private void FlowsListDrop_TextBlock_PreviewMouseMove(object sender, MouseEventArgs e)
        {
            FrameworkElement? fe = sender as FrameworkElement;

            if (fe != null && e.LeftButton == MouseButtonState.Pressed)
            {
                fe = (FrameworkElement)e.OriginalSource;
                if (fe is null)
                    return;
                while (fe!.DataContext is not AdvancedParametersSchemeModule)
                {
                    fe = VisualTreeHelper.GetParent(fe) as FrameworkElement;
                    if (fe is null)
                        return;
                }
                Tools.GetParent<ListBox>(fe, out ListBox? listbox);
                DragDrop.DoDragDrop(fe, new DataObject(new DragDropData(typeof(AdvancedParametersSchemeModule), typeof(ListBox), $"{listbox!.Name}", sender, fe.DataContext)), DragDropEffects.Copy);
            }
        }

        private void FlowsList_PreviewDrop(object sender, DragEventArgs e)
        {
            DragDropData? dragDropData = e.Data.GetData(typeof(DragDropData)) as DragDropData;
            if (e.Effects != DragDropEffects.Copy || dragDropData == null || dragDropData.Data is not AdvancedParametersSchemeModule DragModule)
                return;

            FrameworkElement? PickItem = e.OriginalSource as FrameworkElement;
            while (PickItem is not ListBoxItem && PickItem is not null)
                PickItem = (FrameworkElement)VisualTreeHelper.GetParent(PickItem);

            AdvancedParametersSchemeModule? PickSource = PickItem?.DataContext as AdvancedParametersSchemeModule;
            ObservableCollection<AdvancedParametersSchemeModule> TargetFlows = FilesMode.Instance.CurrentPrest.Flows;
            
            if (TargetFlows.Contains(DragModule))
            {
                //拖拽到空白区，直接最后一个
                if (PickItem is null)
                {
                    TargetFlows.Move(TargetFlows.IndexOf(DragModule), TargetFlows.Count - 1);
                    return;
                }
                if (PickSource is null)
                    return;
                TargetFlows.Move(TargetFlows.IndexOf(DragModule), GetPickIndex(TargetFlows, e, PickItem, PickSource));
            }
            else
            {
                //拖拽到空白区，直接最后一个
                if (PickItem is null)
                {
                    TargetFlows.Add(DragModule.DeepCopy());
                    return;
                }
                if (PickSource is null)
                    return;
                TargetFlows.Insert(GetPickIndex(TargetFlows, e, PickItem, PickSource), DragModule.DeepCopy());
            }
        }
        private int GetPickIndex(ObservableCollection<AdvancedParametersSchemeModule> Source, DragEventArgs e, FrameworkElement PickFrameworkElement, AdvancedParametersSchemeModule PickData)
        {
            double MouseY = e.GetPosition(PickFrameworkElement).Y;
            double CenterY = PickFrameworkElement.ActualHeight / 2;

            int PickIndex = Source.IndexOf(PickData!);

            if (MouseY > CenterY)
                ++PickIndex;
            if (PickIndex < 0)
                PickIndex = 0;
            if (PickIndex >= Source.Count)
                PickIndex = Source.Count - 1;
            return PickIndex;
        }
        #endregion

        private void FileItemRightButtonContextMenuItem_Click(object sender, RoutedEventArgs e)
        {
            if (sender is not MenuItem menuItem)
                return;
            if (menuItem.Parent is not ContextMenu cm)
                return;
            if (ContextMenuService.GetPlacementTarget(cm) is not FrameworkElement fe)
                return;

            switch (menuItem.Tag)
            {
                case "OpenPlayer":
                    Tools.Explorer(((Mode.Files.FileInfo)fe.DataContext).FullPath);
                    return;
                case "Delete":
                    FilesMode.Instance.FileInfos.Remove((Mode.Files.FileInfo)fe.DataContext);
                    return;
                case "OpenTo":
                    Tools.Explorer(((Mode.Files.FileInfo)fe.DataContext).FullPath);
                    return;
            }
        }

        private void RemoveAllFiles_Button_Click(object sender, RoutedEventArgs e)
        {
            FilesMode.Instance.FileInfos.Clear();
        }
    }
}
